
;;;  Artur Cardoso Cançado Gontijo     074776
;;;  Roblêdo Camilo de Alencar         074990


SEGMENT CODE    	          	; segmento de codigo
..start:	                  	; ponto de entrada do programa
 
	MOV AX , DATA           	; inicializa DS
	MOV DS , AX
	MOV AX , STACK          	; inicializa pilha ( SS : SP )
	MOV SS , AX
	MOV SP , STACKTOP

;;;PARTE 1 - Pega o nome do arquivo
;;;e guarda em um vetor com nome ARQUIVO
	
	MOV CX, 0x00
	MOV CL, [ES:80h]
	DEC CL				;coloca em CX o tamanho do nome do arquivo
	MOV DI, 0
	
PEGA_NOME:
	
	MOV AL, [ES:82h+DI]		;copia os elementos do nome do arquivo a partir de ES:82h para pular espaço 
	MOV [ARQUIVO+DI], AL		;passa o nome do arquivo para a variavel ARQUIVO
	INC DI				;aumenta DI para pegah o proximo caractere
	LOOP PEGA_NOME
	
	MOV AL, 0			;insere o 0
	MOV [ARQUIVO+DI], AL		;que indica o final do nome do arquivo
  
;;PARTE 2 Abrindo o Arquivo
ABRE:
	
	MOV AH, 0x3D			;para ler
	MOV AL, 0h			;modo de apenas leitura
	MOV DX, ARQUIVO			;coloca em DX o endereco do nome do arquivo
	INT 21h				;chama instrucao para abrir o arquivo
	JC ERRO_ABERTURA
	
	MOV [FILEHANDLE], AX		;guardando o File Handle do arquivo
	JMP LEITURA

ERRO_ABERTURA:

	;; IMPRIME ERRO CASO NÃO CONSIGA ABRIR O ARQUIVO
	MOV DX, MSG_INVALIDO
	MOV AH, 9h
	INT 21h
	JMP FIM
 
;;PARTE 3 lendo o arquivo	
	
LEITURA:
;;; FAZ A LEITURA DE NO MAX 64K DO ARQUIVO, QUE É SEU TAMANHO MAXIMO
	PUSH DS
	MOV AH, 0x3F
	MOV BX, [FILEHANDLE]
	MOV CX, 0xFFFF
	MOV DX, IMAGEMSEG
	MOV DS, DX
	MOV DX, IMAGEM
	INT 21H
	POP DS
	MOV [TAM_LIDO], AX
	MOV AH, 0x3E
	MOV BX, [FILEHANDLE]
	INT 0x21

;;;PARTE 4 lendo o file header da imagem
;;;Verifica se eh BMP
	MOV DX, IMAGEMSEG
	MOV ES, DX
	XOR CX, CX
	MOV CX, [ES:IMAGEM+0x00]
	CMP CL, 'B'
	JNE VER_BMP
	XOR CX, CX
	MOV CX, [ES:IMAGEM+0x01]
	CMP CL, 'M'
	JNE VER_BMP
;;;Verifica se há 24Bits por Pixel
	XOR CX, CX
	MOV CL, [ES:IMAGEM+0x1C]
	CMP CL, 24
	JNE VER_BITPIXEL
;;;Verifica se há Compressao
	XOR CX, CX
	MOV CX, [ES:IMAGEM+0x1E]
	CMP CL, 0
	JNE VER_COMPRESSAO
	JMP ARQUIVO_VALIDO
	
VER_BITPIXEL:
	
	MOV DX, MSG_INV_BITPIXEL
	MOV AH, 9h
	INT 21h
	MOV AH, 0x4C
	INT 21h
	
VER_COMPRESSAO:
	
	MOV DX, MSG_INV_COMP
	MOV AH, 9h
	INT 21h
	MOV AH, 0x4C
	INT 21h

VER_BMP:
	
	MOV DX, MSG_INV_BMP
	MOV AH, 9h
	INT 21h
	MOV AH, 0x4C
	INT 21h
	
;;; Caso o arquivo seja VALIDO...
;;; PEGA A LARGURA E A ALTURA, PEGA TAMBEM O TAMANHO TOTAL DO PIXEL MAP
ARQUIVO_VALIDO:

	MOV DX, MSG_VALIDO		;o arquivo eh valido para a execucao do programa
	MOV AH, 9h
	INT 21h

	MOV AH, 2h
	MOV DL, 0Dh			; coloca o cursor no inicio da linha
	INT 21h				; executa
	MOV DL, 0Ah			; new line
	INT 21h	
	
	MOV DX, MSG_AGUARDE
	MOV AH, 9h
	INT 21h
	
	MOV AX, 3h
	PUSH DS
	MOV DX, IMAGEMSEG
	MOV DS, DX
	MOV CX, [IMAGEM+0x12]
	POP DS
	MUL CX
	MOV [LARGURABYTE], AX
	MOV [LARGURAPIXEL], AX
	;; completa a largura para um multiplo de 4
	AND AX, 0X0003
	MOV CX, 4
	SUB CX, AX
	CMP CX, 4
	JE CONTINUA
	ADD [LARGURABYTE], CX
	
CONTINUA:
	PUSH DS
	MOV DX, IMAGEMSEG
	MOV DS, DX
	MOV CX, [IMAGEM+0x16]
	POP DS
	MOV [ALTURA], CX
	PUSH DS
	MOV DX, IMAGEMSEG
	MOV DS, DX
	MOV CX, [IMAGEM+0X02]
	POP DS
	MOV [TAMANHO], CX
	SUB WORD [TAMANHO], 0X36
        
;;;CIRCULANDO OS OBJETOS
	MOV WORD [HEADER], 0X0036
	MOV SI,0X00
	XOR DI,DI
	;; FAZ ALTURA*LARGURA, PARA SABER QTOS PIXELS TEM A IMAGEM E QUANTAS VEZES DEVE SER EXECUTADO O LOOP DE PINTA
	XOR DX, DX
	MOV AX, [ALTURA]
	PUSH DS
	MOV DX, IMAGEMSEG
	MOV DS, DX
	MOV CX, [IMAGEM+0X12]
	POP DS
	MUL CX
	MOV CX, AX
	MOV WORD [LINHA], 0X0000
	
;;; FUNÇÃO QUE ANALISA PIXEL POR PIXEL E PINTA OS PIXELS BRANCO AO REDOR  DE VERMELHO, CASO O
;;; PIXEL ANALISADO SEJA PRETO
PINTA:
	PUSH SI
	CALL VERIFICA
	CMP DX,0
	JZ CHAMACIRCULA
RETORNO1:	
	POP SI
	ADD SI, 3
	CMP SI, [LARGURAPIXEL]
	JE ATUALIZA
RETORNO2:	
	LOOP PINTA
	JMP CRIA
;;; A CADA VEZ QUE SI ALCANÇA O TAMANHO DE UMA LINHA
;;; INCREMENTA O CONTADOR DE LINHAS DI
;; E SOMA A A LARGURA DE LINHA EM "LINHA", ISTO É, [LINHA]=DI*[LARGURABYTE]
ATUALIZA:
	MOV SI, 0X00
	INC DI
	MOV AX, [LARGURABYTE]
	ADD [LINHA],AX
	JMP RETORNO2
CRIA:	

	MOV AH, 0x3C              
	MOV CX, 0x00
	MOV DX, SAIDA			 
	INT 0x21
	MOV [FILEHANDLE], AX     

GRAVA:	
	MOV AH, 0x40
	MOV BX, [FILEHANDLE]
	MOV CX, [TAM_LIDO]
	MOV DX, IMAGEMSEG
	MOV DS, DX
	MOV DX, IMAGEM
	INT 0x21 
 
	MOV AH, 0x3E
	MOV BX, [FILEHANDLE]
	INT 0x21

FIM:	
	MOV AH, 0x4C
	INT 21h
	
;;; CHAMA A FUNÇÃO QUE CIRCULA OS PIXELS PRETOS
CHAMACIRCULA:
	CALL CIRCULA
	JMP RETORNO1

CIRCULA	
	PUSH BP
	PUSH SI
	PUSH WORD [LINHA]
	MOV BP, SP
	MOV SI, [BP+8]
;;; VERIFICA PIXEL A ESQUERDA
	ADD SI, 3
	;; CASO ESTEJA O PIXEL A SER CIRCULA ESTEJA NA ULTIMA COLUNA DA ESQUERDA
;;; NÃO TENTA CIRCULAR NENHUM DOS 3 A ESQUERDA
	CMP SI,[LARGURAPIXEL]
	JE LBL2
	PUSH SI
	CALL VERIFICA
	MOV BYTE [CODIGO], 0
	POP SI
	CMP DX, 1
	JZ  CHAMAMUDA
LBL0:	
;;; VERIFICA PIXEL SUPERIOR ESQUERDO
	MOV AX, [LARGURABYTE]
	ADD [LINHA],AX
	MOV AX, [ALTURA]
	DEC AX
	CMP DI, AX
	JE LBL1
	PUSH SI
	CALL VERIFICA
	MOV BYTE [CODIGO], 1
	POP SI
	CMP DX, 1
	JZ  CHAMAMUDA
;;; VERIFICA PIXEL INFERIOR ESQUERDO
LBL1:
	MOV AX, [LARGURABYTE]
	MOV BX, [BP]
	MOV [LINHA], BX
	SUB [LINHA], AX
	CMP DI, 0
	JE LBL2
	PUSH SI
	CALL VERIFICA
	MOV BYTE [CODIGO], 2
	POP SI
	CMP DX, 1
	JZ CHAMAMUDA
;;; VERIFICA PIXEL DIREITO
LBL2:
	MOV SI, [BP+8]
	CMP SI, 0X00
;;; FAZ O MESMO PROCESSO USADO PARA O ESQUERDO
	JE LBL7
	SUB SI,3
	PUSH SI
	CALL VERIFICA
	MOV BYTE [CODIGO], 7
	POP SI
	CMP DX, 1
	JZ CHAMAMUDA
	JMP LBL7
CHAMAMUDA:
;; CHAMA A FUNÇÃO QUE PINTA O PIXEL BRANCO DE VERMELHO
;;; E RETONA PARA LOGO DEPOIS DE ONDE ELA FOI CHAMADA
	PUSH SI
	CALL MUDA
	POP SI
	CMP BYTE [CODIGO], 0
	JE LBL0
	CMP BYTE [CODIGO], 1
	JE LBL1
	CMP BYTE [CODIGO], 2
	JE LBL2
	CMP BYTE [CODIGO], 7
	JE LBL7
	CMP BYTE [CODIGO], 3
	JE LBL3
	CMP BYTE [CODIGO], 4
	JE LBL4
	CMP BYTE [CODIGO], 5
	JE LBL55
	CMP BYTE [CODIGO], 6
	JE LBL66
LBLX:
	JMP LBL4
LBL7:	
;;; VERIFICA PIXEL SUPERIOR DIREITO
	MOV AX, [LARGURABYTE]
	MOV BX, [BP]
	MOV [LINHA], BX
	ADD [LINHA], AX
	MOV AX, [ALTURA]
	DEC AX
	CMP DI, AX
	JE LBL3
	PUSH SI
	CALL VERIFICA
	MOV BYTE [CODIGO], 3
	POP SI
	CMP DX, 1
	JZ CHAMAMUDA
;;; VERIFICA PIXEL INFERIOR DIREITO
LBL3:	
	MOV AX, [LARGURABYTE]
	MOV BX, [BP]
	MOV [LINHA], BX
	SUB [LINHA], AX
	CMP DI, 0
	JE LBL4
	PUSH SI
	CALL VERIFICA
	MOV BYTE [CODIGO], 4
	POP SI
	CMP DX, 1
	JZ CHAMAMUDA
	JMP LBL4
LBL66:
	JMP LBL6
	;;; VERIFICA PIXEL SUPERIOR
LBL55:
	JMP LBL5
LBL4:	
	MOV SI, [BP+8]
	MOV AX, [LARGURABYTE]
	MOV BX, [BP]
	MOV [LINHA], BX
	ADD [LINHA], AX
	MOV AX, [ALTURA]
	DEC AX
	CMP DI, AX
	JE LBL5
	PUSH SI
	CALL VERIFICA
	MOV BYTE [CODIGO], 5
	POP SI
	CMP DX, 1
	JZ CHAMAMUDA
;;; VERIFICA PIXEL INFERIOR
LBL5:	
	MOV AX, [LARGURABYTE]
	MOV BX, [BP]
	MOV [LINHA], BX
	SUB [LINHA], AX
	CMP DI, 0
	JE LBL6
	PUSH SI
	CALL VERIFICA
	MOV BYTE [CODIGO], 6
	POP SI
	CMP DX, 1
	JZ CHAMAMUDA
LBL6:
	POP WORD [LINHA]
	POP SI
	POP BP
	RET
;;; FUNÇÃO QUE PINTA O PIXEL BRANCO DE VERMELHO
;;; TIRANDO SUAS COMPNENTE BLUE E GREEN
MUDA
	PUSH BP
	PUSH DS
	MOV BP, SP
	MOV BX, [BP+6]
	ADD BX, [LINHA]
	ADD BX, [HEADER]
	MOV DX, IMAGEMSEG
	MOV DS, DX
	MOV BYTE [IMAGEM+BX],0X00
	INC BX
	MOV BYTE [IMAGEM+BX],0X00
	POP DS
	POP BP
	RET
;;;VERIFICA SE O PIXEL EH PRETO, BRANCO OU VERMELHO
;;; O RETORNO EH DADO EM CX
;;; DX = 0 É PRETO
;;; DX = 1 É BRANCO
;;; DX = 2 É VERMELHO
;;; CASO SEJA PRETO, PINTARÁ TODOS OS BRANCOS
;;; AO REDOR DE VERMELHO
VERIFICA
	PUSH BP
	PUSH DS
	MOV BP, SP
	MOV BX, [BP+6]
	ADD BX, [HEADER]
	ADD BX, [LINHA]
	MOV DX, IMAGEMSEG
	MOV DS, DX
	CMP BYTE [IMAGEM+BX], 0XFF
	JZ BRANCO
	INC BX
	INC BX
	CMP BYTE [IMAGEM+BX],0XFF
	JZ VERMELHO
	MOV DX, 0
	POP DS
	POP BP
	RET
	
BRANCO:
	MOV DX, 1
	POP DS
	POP BP
	RET
VERMELHO:
	MOV DX, 2
	POP DS
	POP BP
	RET
	
ALIGN 16
SEGMENT DATA                 ; segmento de dados
	CODIGO RESB 1
	HEADER RESB 2
	FILEHANDLE DW 0
	MSG_VALIDO db "====     Arquivo Valido     ====$"
	MSG_INVALIDO db "====    Arquivo Invalido    ====$"
	MSG_INV_BITPIXEL db "==== Arquivo sem 24Bits por Pixel ====$"
	MSG_INV_COMP db "==== Arquivo Comprimido ====$"
	MSG_INV_BMP db "==== Arquivo Nao eh BMP ====$"
	MSG_AGUARDE db "==== Circulando, Aguarde... ====$"
	SAIDA DB 'saida.bmp',0
	TAM_LIDO RESB 2
        ALTURA RESB 2
	LARGURAPIXEL RESB 2
	LARGURABYTE RESB 2
	TAMANHO RESB 2
	ARQUIVO RESB 127
	LINHA RESB 2

ALIGN 16
SEGMENT IMAGEMSEG
	IMAGEM RESB 0xFFFF
	
ALIGN 16
SEGMENT STACK stack         ; segmento de pilha

	RESB 256
	STACKTOP:
